#include "HttpServer.hpp"

#include <memory> // unique_ptr ...... 智能指针的头文件

using namespace std;
using namespace server;

// 使用手册
void Usage(void *proc)
{
    std::cerr << "\nUsage:\r\n"
              << proc << " serverport";
}

std::string suffixToDesc(const std::string suffix)
{
    std::string ct = "Content-Type: ";
    if (suffix == ".html")
        ct += "text/html";
    else if (suffix == ".jpg")
        ct += "application/x-jpg;image/jpeg";
    ct += "\r\n";

    return ct;
}

// 让 httpserver 执行 http 协议的 GET 方法
// 1. 服务器和网页分离，html
// 2. url -> / : web根目录
// 3. 我们要正确的给客户端返回资源类型，我们首先要自己知道！所有的资源都有后缀！！
bool GET(const HttpRequest &req, HttpResponse &resp)
{
    // if(req.path == "test.py")
    // {
    //     //建立进程间通信，pipe
    //     //fork创建子进程，execl("/bin/python", test.py)
    //     // 父进程，将req.parm 通过管道写给某些后端语言，py，java，php等语言
    // }
    // if(req.path == "/search")
    // {
    //     // req.parm
    //     // 使用我们自己写的C++的方法，提供服务
    // }
    // for test

    cout << "------------------------http start-------------------------" << endl;
    cout << req.inbuffer << std::endl;
    std::cout << "method: " << req.method << std::endl;
    std::cout << "url: " << req.url << std::endl;
    std::cout << "httpversion: " << req.httpversion << std::endl;
    std::cout << "path: " << req.path << std::endl;
    std::cout << "suffix: " << req.suffix << std::endl;
    std::cout << "size: " << req.size << "字节" << std::endl;
    cout << "----------------------http end---------------------------" << endl;

    // std::string respline = "HTTP/1.1 500 Temporary Redirect\r\n";
    std::string respline = "HTTP/1.1 200 OK\r\n";
    std::string respheader = suffixToDesc(req.suffix);
    if (req.size > 0)
    {
        // 下面的 std::string body; 的大小也得加上的哦，而且body的大小还得resize大一点哦
        // respheader += "Content-Length: ";
        // respheader += std::to_string(req.size);
        // respheader += "\r\n";
    }

    // 加上下面这一行的作用是 ：
    // --> http 状态码为301的永久重定向的作用 --> 可能是因为平台进行了比较大的更新，更新到了一个全新的平台太上
    // 对于有些软件需要更新的可能有些人不愿意更新，当然也会保留旧的版本。手机os也是，网站也是......
    // respheader += "Location: https://www.qq.com/\r\n";
    // 307 为临时重定向
    std::string respblank = "\r\n";

    // 这个代码不行有问题的，图片显示不出来的
    // std::string body;
    // if (Util::readFile(req.path, &body) == false)
    // {
    //     // 如果没有请求资源的路径是空的话，会返回一个 404 的页面
    //     Util::readFile(html_404, &body); // 一定能成功
    // }

    std::string body;
    body.resize(req.size + 1); // 底层可能是转成用的c类型数组的接口，所以多开一点
    if (Util::readFile(req.path, (char *)body.c_str(), req.size) == false)
    {
        // 如果没有请求资源的路径是空的话，会返回一个 404 的页面
        Util::readFile(html_404, (char *)body.c_str(), req.size); // 一定能成功
    }
    respheader += "Content-Length: ";
    respheader += std::to_string(body.size());
    respheader += "\r\n";

    resp.outbuffer += respline;
    resp.outbuffer += respheader;
    resp.outbuffer += respblank;

    cout << "----------------------http response start---------------------------" << endl;
    std::cout << resp.outbuffer << std::endl;
    cout << "----------------------http response end---------------------------" << endl;

    resp.outbuffer += body;

    return true;
}

// ./httpserver serverport
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }
    uint16_t serverport = atoi(argv[1]);

    unique_ptr<HttpServer> ht(new HttpServer(GET, serverport));
    // 功能路由!
    // httpsvr->registerCb("/", Get);
    // httpsvr->registerCb("/search", Search);
    // httpsrv->registerCb("/test.py", Other);
    ht->initServer();
    ht->start();

    return 0;
}